package com.jlpay.open.jlpay.sdk.java.utils.gm;


import com.jlpay.open.jlpay.sdk.java.utils.gm.keyentity.HsmKeyPair;

import javax.crypto.KeyGenerator;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

/**
 * @author zhangyinda
 * @since 2024/2/20
 */
public class KeyGenerateUtils {
    public static String generateAesKey(int keySize) {
        try {
            KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
            keyGenerator.init(keySize);
            byte[] encoded = Base64.getEncoder().encode(keyGenerator.generateKey().getEncoded());
            return new String(encoded);
        } catch (Exception e) {
            throw new RuntimeException("Generate Aes key fail: " + e.getMessage());
        }
    }

    public static String generateSm4Key(int keySize) {
        try {
            byte[] key = Sm4Utils.generateKey(keySize);
            byte[] encoded = Base64.getEncoder().encode(key);
            return new String(encoded);
        } catch (Exception e) {
            throw new RuntimeException("Generate Sm4 key fail: " + e.getMessage());
        }
    }

    public static HsmKeyPair generateRsaKey(int keySize) {
        try {
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            keyPairGenerator.initialize(keySize);
            KeyPair keyPair = keyPairGenerator.generateKeyPair();

            String pubicKey = new String(Base64.getEncoder().encode(keyPair.getPublic().getEncoded()));
            String privateKey = new String(Base64.getEncoder().encode(keyPair.getPrivate().getEncoded()));

            return new HsmKeyPair(pubicKey, privateKey);
        } catch (Exception e) {
            throw new RuntimeException("Generate Rsa key fail: " + e.getMessage());
        }
    }

    public static HsmKeyPair generateSm2Key() {
        try {
            KeyPair keyPair = Sm2Utils.generateKeyPair();
            String pubicKey = generatePemFormat(keyPair.getPublic());
            String privateKey = generatePemFormat(keyPair.getPrivate());

            return new HsmKeyPair(pubicKey, privateKey);
        } catch (Exception e) {
            throw new RuntimeException("Generate Sm2 key fail: " + e.getMessage());
        }
    }

    private static String generatePemFormat(PrivateKey privateKey) {
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKey.getEncoded());
        String begin = "-----BEGIN PRIVATE KEY-----";
        String end = "-----END PRIVATE KEY-----";
        return begin + System.lineSeparator() + Base64.getMimeEncoder().encodeToString(pkcs8EncodedKeySpec.getEncoded()) + System.lineSeparator() + end;
    }

    private static String generatePemFormat(PublicKey publicKey) {
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKey.getEncoded());
        String begin = "-----BEGIN PUBLIC KEY-----";
        String end = "-----END PUBLIC KEY-----";
        return begin + System.lineSeparator() + Base64.getMimeEncoder().encodeToString(x509EncodedKeySpec.getEncoded()) + System.lineSeparator() + end;
    }
}
